package com.changgou.seckill.consumer;

import com.alibaba.fastjson.JSON;
import com.changgou.entity.SystemConstants;
import com.changgou.seckill.dao.SeckillGoodsMapper;
import com.changgou.seckill.dao.SeckillOrderMapper;
import com.changgou.seckill.pojo.SeckillGoods;
import com.changgou.seckill.pojo.SeckillOrder;
import com.changgou.seckill.pojo.SeckillStatus;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Created by zhangyuhong
 * Date:2020/5/25
 */
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
//秒杀下单的监听
@Component
@RabbitListener(queues = "${mq.pay.queue.seckillorder}")  //监听这个队列,${}表示对象  也可以直接写值
public class SeckillOrderPayMessageListener {

    @Autowired
    private SeckillOrderMapper seckillOrderMapper;

    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 监听消费消息
     *
     * @param message
     */
    @RabbitHandler
    public void consumeMessage(@Payload String message) {  //@Payload:有效载荷，有效负荷，有效载重”。就是对于接收者有用的数据
        //1.获取字符串转成map
        Map<String, String> map = JSON.parseObject(message, Map.class);//整个传递的数据
        System.out.println("监控秒杀队列的数据:" + map);
        String out_trade_no = map.get("out_trade_no");
        String attach = map.get("attach");
        Map<String, String> attachMap = JSON.parseObject(attach, Map.class);
        if (map != null && map.get("return_code").equalsIgnoreCase("SUCCESS")) {
            //支付成功
            if (map.get("result_code").equalsIgnoreCase("SUCCESS")) {
                //2.获取订单的ID  获取交易流水 获取支付时间
                SeckillOrder seckillOrder = (SeckillOrder) redisTemplate.boundHashOps(SystemConstants.SEC_KILL_ORDER_KEY).get(attachMap.get("username"));
                if (seckillOrder != null) {
                    System.out.println("严重错误,redis缓存里找不到用户的订单,是不是已经被消费了?");
                }
                //3.更新订单
                seckillOrder.setStatus("1");//已经支付
                String time_end = map.get("time_end");//支付时间

                //jota-time.jar
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
                try {
                    Date parse = simpleDateFormat.parse(time_end);
                    seckillOrder.setPayTime(parse);//设置支付时间
                } catch (Exception e) {
                    e.printStackTrace();
                }
                String transaction_id = map.get("transaction_id");   //微信支付订单号
                seckillOrder.setTransactionId(transaction_id);
                seckillOrderMapper.insertSelective(seckillOrder);

                redisTemplate.boundHashOps(SystemConstants.SEC_KILL_ORDER_KEY).delete(attachMap.get("username"));//清空redis中的订单
                redisTemplate.boundHashOps(SystemConstants.SEC_KILL_QUEUE_REPEAT_KEY).delete(attachMap.get("username"));//删除排队信息

                redisTemplate.boundHashOps(SystemConstants.SEC_KILL_USER_STATUS_KEY).delete(attachMap.get("username"));//删除抢单信息
            } else {
                RLock mylock = redissonClient.getLock("Mylock");
                boolean locked = false;

                //  支付失败----> 删除订单 ---》恢复库存---》积分恢复
                // 调用关闭订单的API 关闭支付订单
                SeckillStatus seckillStatus = (SeckillStatus) redisTemplate.boundHashOps(SystemConstants.SEC_KILL_USER_STATUS_KEY).get(attachMap.get("username"));


                try {
                    //上锁
//                    mylock.lock(100, TimeUnit.SECONDS);
                    locked = mylock.tryLock(100, TimeUnit.SECONDS);
                    if (locked) {
                        //恢复库存
                        SeckillGoods seckillGoods = (SeckillGoods) redisTemplate.boundHashOps(SystemConstants.SEC_KILL_GOODS_PREFIX + seckillStatus.getTime()).get(seckillStatus.getGoodsId());

                        if (seckillGoods == null) {
                            seckillGoods = seckillGoodsMapper.selectByPrimaryKey(seckillStatus.getGoodsId());
                        }
                        seckillGoods.setStockCount(seckillGoods.getStockCount() + 1);

                        redisTemplate.boundHashOps(SystemConstants.SEC_KILL_GOODS_PREFIX + seckillStatus.getTime()).put(seckillStatus.getGoodsId(), seckillGoods);


                        redisTemplate.boundHashOps(SystemConstants.SEC_KILL_ORDER_KEY).delete(attachMap.get("username"));//清空redis中的订单
                        redisTemplate.boundHashOps(SystemConstants.SEC_KILL_QUEUE_REPEAT_KEY).delete(attachMap.get("username"));//删除排队信息
                        redisTemplate.boundHashOps(SystemConstants.SEC_KILL_USER_STATUS_KEY).delete(attachMap.get("username"));//删除抢单信息
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (locked) {
                        mylock.unlock();
                    }
                }

            }
        }
    }
}
